package com.grj.handler;

import com.grj.utils.HttpUtils;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.multipart.*;
import io.netty.util.CharsetUtil;
import org.apache.commons.io.FilenameUtils;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

public class HttpServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> {


    private HttpPostRequestDecoder decoder;


    @Override
    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {


        // 检查是否是文件上传
        HttpHeaders headers = request.headers();
        String contentType = headers.get(HttpHeaderNames.CONTENT_TYPE);
        String body = request.content().toString(CharsetUtil.UTF_8);


        // 获取请求方法和URI
        HttpMethod method = request.method();
        String uri = request.uri();

        System.out.println("收到请求: " + method + " " + uri);

        // 构建响应
        FullHttpResponse response;
        String content = "";

        try {
            if (HttpMethod.GET.equals(method)) {
                content = handleGetRequest(uri, body, request);
            } else if (HttpMethod.POST.equals(method)) {
                content = handlePostRequest(uri, body, request);
            } else {
                content = "{\"error\": \"不支持的HTTP方法\"}";
            }

            response = HttpUtils.createResponse(HttpResponseStatus.OK, content, "application/json");

        } catch (Exception e) {
            content = "{\"error\": \"服务器内部错误: " + e.getMessage() + "\"}";
            response = HttpUtils.createResponse(HttpResponseStatus.INTERNAL_SERVER_ERROR, content, "application/json");
        }

        // 发送响应
        ctx.writeAndFlush(response);
    }

    private String handleGetRequest(String uri, String body, FullHttpRequest request) {
        Map<String, Object> result = new HashMap<>();

        if ("/".equals(uri) || "/hello".equals(uri)) {
            result.put("message", "Hello, Netty HTTP Server!");
            result.put("status", "success");
        } else if (uri.startsWith("/user/")) {
            String userId = uri.substring("/user/".length());
            result.put("userId", userId);
            result.put("name", "用户" + userId);
            result.put("status", "success");
        } else {
            result.put("error", "接口不存在");
            result.put("status", "fail");
        }

        return HttpUtils.toJson(result);
    }

    private String handlePostRequest(String uri, String body, FullHttpRequest request) {
        Map<String, Object> result = new HashMap<>();

        // 移动目录, 解压
        if ("/api/login".equals(uri)) {
            // 简单的登录模拟
            result.put("message", "登录成功");
            result.put("token", "mock-jwt-token");
            result.put("status", "success");
        } else if ("/api/data".equals(uri)) {
            result.put("received", body);
            result.put("status", "success");
        } else if ("/api/upload".equals(uri)) {

            // 接受文件
            String s = handleFileUpload(request);

            result.put("status", "success");

        } else {
            result.put("error", "接口不存在");
            result.put("status", "fail");
        }

        return HttpUtils.toJson(result);
    }


    /**
     * 处理文件上传
     *
     * @param ctx
     * @param request
     */
    private String handleFileUpload(FullHttpRequest request) {
        String content = "";
        try {
            // 创建临时目录用于存储上传文件
            File uploadDir = new File("uploads");
            if (!uploadDir.exists()) {
                uploadDir.mkdirs();
            }

            // 初始化文件上传解码器
            HttpDataFactory factory = new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE);
            decoder = new HttpPostRequestDecoder(factory, request);

            Map<String, Object> result = new HashMap<>();

            // 处理上传数据
            while (decoder.hasNext()) {
                InterfaceHttpData data = decoder.next();
                if (data != null) {
                    try {
                        switch (data.getHttpDataType()) {
                            case Attribute:
                                Attribute attribute = (Attribute) data;
                                result.put(attribute.getName(), attribute.getValue());
                                break;
                            case FileUpload:
                                FileUpload fileUpload = (FileUpload) data;
                                String baseName = FilenameUtils.getBaseName(fileUpload.getFilename());
                                String extension = FilenameUtils.getExtension(fileUpload.getFilename());
                                if (fileUpload.isCompleted()) {
                                    // 保存文件
                                    File dest = new File(uploadDir, fileUpload.getFilename());
                                    fileUpload.renameTo(dest);

                                    result.put("filename", fileUpload.getFilename());
                                    result.put("size", fileUpload.length());
                                    result.put("savedPath", dest.getAbsolutePath());
                                    result.put("status", "success");
                                }
                                break;
                            default:
                                break;
                        }

                    } finally {
                        data.release();
                    }
                }
            }

            content = HttpUtils.toJson(result);

        } catch (Exception e) {
            content = "{\"error\": \"文件上传失败: " + e.getMessage() + "\"}";
        } finally {
            if (decoder != null) {
                decoder.destroy();
            }
        }
        return content;
    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }
}
